from datetime import datetime
from functools import wraps
from flask import jsonify,current_app
from flask_jwt_extended  import (
    verify_jwt_in_request,
    get_jwt, create_access_token,
    create_refresh_token,
    get_jti,
    current_user
)
from myapp import jwt
from myapp.models import User
from myapp.utils.reposeUtils import ApiResponse

def authenticate(username, password):
    """用户认证"""
    user = User.query.filter_by(login_name=username).first()
    if user and user.check_password(password):
        return user
    return None

@jwt.user_lookup_loader
def user_lookup_callback(_jwt_header, jwt_data):
    identity = jwt_data["sub"]
    if not identity:
        return ApiResponse.unauthorized()

    current_user = User.query.get(identity);
    if not current_user:
        return ApiResponse.unauthorized()

    return current_user

@jwt.invalid_token_loader
def custom_invalid_token_callback(error_string):
    print(error_string)
    # 直接返回简单的401响应，不显示具体错误
    return ApiResponse.unauthorized()

def create_tokens(user):
    """创建关联的Token对"""
    access_token = create_access_token(
        identity=user.id,
        fresh=True
    )
    refresh_token = create_refresh_token(
        identity=user.id
    )

    # 记录Token关联关系
    access_jti = get_jti(access_token)
    refresh_jti = get_jti(refresh_token)

    permissions = set()  # 使用集合去重
    for role in user.roles:
        for resource in role.resources:
            permissions.add(resource)

    # 在refresh token中存储access token的jti
    refresh_claims = {
        'linked_access_jti': access_jti,
        'permissions': [resource.to_json() for resource in permissions]
    }
    refresh_token = create_refresh_token(
        identity=user.id,
        additional_claims=refresh_claims
    )

    # 计算并格式化到期时间
    now = datetime.now()
    access_expiry = (now + current_app.config['JWT_ACCESS_TOKEN_EXPIRES']).strftime("%Y-%m-%d %H:%M:%S")
    refresh_expiry = (now + current_app.config['JWT_REFRESH_TOKEN_EXPIRES']).strftime("%Y-%m-%d %H:%M:%S")

    return {
        'accessToken': access_token,
        'refreshToken': refresh_token,
        'expires': access_expiry,
        'refreshExpires': refresh_expiry,
        # 'tokenType': 'Bearer'
    }

def refresh_access_token():
    """使用Refresh Token获取新的Access Token"""
    # 自动从当前请求获取Refresh Token并验证
    new_access_token = create_access_token(
        identity=current_user.id,
        fresh=False  # 标记为非新鲜Token（通过刷新获取的）
    )

    return {
        "access_token": new_access_token,
        "expires_in": int(current_app.config['JWT_ACCESS_TOKEN_EXPIRES'].total_seconds())
    }

def permission(permission_code):
    """权限检查装饰器"""

    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            verify_jwt_in_request()
            claims = get_jwt()
            if permission_code not in claims.get('permissions', []):
                return jsonify({
                    'error': 'Forbidden',
                    'message': '用户权限不足！'
                }), 403
            return fn(*args, **kwargs)
        return wrapper
    return decorator

def refresh_access_token():
    """使用Refresh Token获取新的Access Token"""
    # 自动从当前请求获取Refresh Token并验证
    new_access_token = create_access_token(
        identity=current_user.id,
        fresh=False  # 标记为非新鲜Token（通过刷新获取的）
    )
    now = datetime.now()
    access_expires_at = (now + current_app.config['JWT_ACCESS_TOKEN_EXPIRES']).strftime("%Y-%m-%d %H:%M:%S")
    return {
        "accessToken": new_access_token,
        "expires": access_expires_at
    }
